﻿using NServiceKit.Redis;
using System;
using System.Collections.Generic;
using System.Linq;

namespace HobSoft.SoccerBet2014.Domain.Implementation.RedisRepository
{
    using IRepositories;
    using Models;
    using Models.KeyHelper;

    public class OddsRepository : ReadWriteRedisRepository<Odds>, IOddsRepository
    {
        public OddsRepository(PooledRedisClientManager pooledRedisClient)
            : base(pooledRedisClient)
        {

        }

        public IList<Odds> GetNewByMarket(params string[] marketKeys)
        {
            if (marketKeys == null)
                throw new ArgumentNullException("marketKeys", "need market keys");
            if (!marketKeys.Any())
                return null;
            List<Odds> result = new List<Odds>();
            using (var redisClient = CreateReadRedisClient())
            {
                var redisMarket = redisClient.As<Market>();
                var redisOdds = redisClient.As<Odds>();
                var marketArray = redisMarket.GetByIds(marketKeys);
                foreach (var mk in marketArray)
                {
                    if (mk.OddsIDS == null || !mk.OddsIDS.Any()) continue;
                    var oddsIds = mk.OddsIDS.Select(k => KeyGenerateHelper.Create<Odds>(mk.BmID, k));
                    var oddsArray = redisOdds.GetByIds(oddsIds);
                    if (oddsArray.Any())
                        result.AddRange(oddsArray);
                }
            }
            return result;
        }

        public IList<Odds> GetNewByMarket(Odds.MarketType type, params string[] marketKeys)
        {
            if (marketKeys == null)
                throw new ArgumentNullException("marketKeys", "need market keys");
            if (!marketKeys.Any())
                return null;
            List<Odds> result = new List<Odds>();
            using (var redisClient = CreateReadRedisClient())
            {
                var redisMarket = redisClient.As<Market>();
                var redisOdds = redisClient.As<Odds>();
                var marketArray = redisMarket.GetByIds(marketKeys);
                foreach (var mk in marketArray)
                {
                    if (mk.OddsIDS == null || !mk.OddsIDS.Any()) continue;
                    var oddsIds = mk.OddsIDS.Select(k => KeyGenerateHelper.Create<Odds>(mk.BmID, k));
                    var oddsArray = redisOdds.GetByIds(oddsIds);
                    if (oddsArray.Any())
                        result.AddRange(oddsArray.Where(o => o.Type == type));
                }
            }
            return result;
        }


        public int Disable(byte bookerId, string host, params string[] oddsIds)
        {
            if (oddsIds.Length == 0) return 0;

            int count = 0;
            using (var redisClient = CreateReadRedisClient())
            {
                var redisMarket = redisClient.As<Market>();
                var redisOdds = redisClient.As<Odds>();
                var keys = oddsIds.Select(o => KeyGenerateHelper.Create<Odds>(bookerId, o));
                var oddsRange = redisOdds.GetByIds(keys);
                var refMarketIds = new Dictionary<string, List<string>>();
                if (!oddsRange.Any()) return 0;
                count = oddsRange.Count;
                foreach (var odds in oddsRange)
                {
                    odds.IsAvailable = false;
                    odds.LastUpdateTime = DateTime.Now;
                    string refMarketId = KeyGenerateHelper.Create<Market>(odds.BmID, odds.GameID, host);
                    if (!refMarketIds.ContainsKey(refMarketId))
                    {
                        refMarketIds.Add(refMarketId, new List<string>());
                    }
                    refMarketIds[refMarketId].Add(odds.OddsID);
                }

                redisOdds.StoreAll(oddsRange);
                var markets = redisMarket.GetByIds(refMarketIds.Keys.ToArray());
                foreach (var mk in markets)
                {
                    var delOddsId = refMarketIds[mk.Key];
                    foreach (var oddsId in delOddsId)
                    {
                        mk.OddsIDS.Remove(oddsId);
                    }
                }
                if (markets.Any())
                    redisMarket.StoreAll(markets);
            }
            return count;
        }
    }
}
